package com.woniuxy.goods.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniuxy.core.util.ObjectCoverUtil;
import com.woniuxy.core.util.StateNum;
import com.woniuxy.goods.client.AdminFeignClient;
import com.woniuxy.goods.dto.AccountDto;
import com.woniuxy.goods.dto.AppraisalRecordsDto;
import com.woniuxy.goods.dto.GoodsDto;
import com.woniuxy.goods.dto.ValueRecordDto;
import com.woniuxy.goods.entity.Goods;
import com.woniuxy.goods.entity.GoodsAppraisalRecords;
import com.woniuxy.goods.entity.GoodsValueRecords;
import com.woniuxy.goods.entity.ProcessExecute;
import com.woniuxy.goods.mapper.GoodsValueRecordsMapper;
import com.woniuxy.goods.param.AddValueParam;
import com.woniuxy.goods.param.FindRecordParam;
import com.woniuxy.goods.service.GoodsService;
import com.woniuxy.goods.service.GoodsValueRecordsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.goods.service.ProcessExecuteService;
import com.woniuxy.openfeign.util.Result;
import com.woniuxy.web.util.ConvertUtil;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 * 评估记录管理服务层实现类
 * @author ...
 * @since 2024年05月22日
 */
@Service
public class GoodsValueRecordsServiceImpl extends ServiceImpl<GoodsValueRecordsMapper, GoodsValueRecords> implements GoodsValueRecordsService {
    /**
     * 流程执行服务层接口
     */
    @Resource
    private ProcessExecuteService executeService;
    /**
     * 商品管理服务层接口
     */
    @Resource
    private GoodsService goodsService;
    /**
     * 系统模块接口
     */
    @Resource
    private AdminFeignClient adminFeignClient;

    /**
     * 新增评估记录
     * @param param 新增评估记录对象
     * @return 评估记录
     * @throws Exception
     */
    @Override
    @GlobalTransactional(rollbackFor = Throwable.class)
    public GoodsValueRecords addValue(AddValueParam param) throws Exception {
        Result result = adminFeignClient.findAdminInfoByAccountId(param.getAccountId());
        if (result.getCode()!=200) throw new Exception(result.getMessage());
        AccountDto account = ObjectCoverUtil.castT(result.getData(), AccountDto.class);
        if (account==null||account.getState()!= StateNum.ACCOUNT_STATE_NORMAL) throw new Exception("评估师异常");
        GoodsDto goods = goodsService.findGoodsById(param.getGoodsId());
        if (goods==null||goods.getProcessExecuteId()!= StateNum.GOODS_PROCESS_NOT_EVAL) throw new Exception("物品异常");
        ProcessExecute execute = executeService.findExecuteByStateNumGoodsId(StateNum.GOODS_PROCESS_NOT_EVAL, param.getGoodsId());
        if (execute.getAccountId()!=param.getAccountId()) throw new Exception("无权限鉴定该物品");
        GoodsValueRecords records = BeanUtil.toBean(param, GoodsValueRecords.class);
        List<GoodsValueRecords> list = findValueByGoodsId(param.getGoodsId());
        if (ObjectUtils.isNotEmpty(list)) {
            records.setModifyBy(account.getAdminName());
            records.setModifyTime(LocalDateTime.now().toString());
        }
        records.setCreateBy(account.getAdminName());
        records.setCreateTime(LocalDateTime.now().toString());
        save(records);
        Goods bean = BeanUtil.toBean(records, Goods.class);
        goodsService.updateGoodsByEntity(bean);
        //修改流程活跃状态
        executeService.updateUpActiveById(execute.getProcessExecuteId());
        return records;
    }

    /**
     * 根据物品id查询历史评估记录
     * @param goodsId 物品id
     * @return 评估记录
     * @throws Exception
     */
    @Override
    @GlobalTransactional(rollbackFor =  Throwable.class)
    public List<GoodsValueRecords> findValueByGoodsId(Integer goodsId) {
        QueryWrapper<GoodsValueRecords> wrapper = new QueryWrapper<>();
        wrapper.eq("goods_id",goodsId);
        wrapper.orderByAsc("create_time");
        return list(wrapper);
    }

    /**
     * 根据物品id查询最新评估记录及历史评估记录
     * @param goodsId 物品id
     * @return 最新评估记录及历史评估记录
     * @throws Exception
     */
    @Override
    public ValueRecordDto findNewValueByGoodsId(Integer goodsId) throws Exception {
        QueryWrapper<GoodsValueRecords> wrapper = new QueryWrapper<>();
        wrapper.eq("goods_id",goodsId);
        wrapper.orderByDesc("create_time");
        wrapper.last("limit 1");
        GoodsValueRecords records = getOne(wrapper);
        ValueRecordDto dto = BeanUtil.toBean(records, ValueRecordDto.class);
        GoodsDto goodsDto = goodsService.findGoodsById(dto.getGoodsId());
        dto.setGoodsName(goodsDto.getGoodsName());
        dto.setGoodsBrand(goodsDto.getBrandName());
        dto.setGoodsCat(goodsDto.getRoute());
        List<GoodsValueRecords> list = findValueByGoodsId(goodsId);
        list.remove(records);
        List<ValueRecordDto> listTo = ConvertUtil.convertListTo(list, ValueRecordDto::new);
        for (ValueRecordDto to : listTo) {
            dto.setGoodsName(goodsDto.getGoodsName());
            dto.setGoodsBrand(goodsDto.getBrandName());
            dto.setGoodsCat(goodsDto.getRoute());
        }
        dto.setOld(listTo);
        return dto;
    }

    /**
     * 查询所有最新的评估记录及历史记录
     * @param param 查询记录参数对象
     * @return 评估记录集合
     * @throws Exception
     */
    @Override
    public IPage<ValueRecordDto> findNewValues(FindRecordParam param) throws Exception {
        Page<GoodsValueRecords> page = new Page<>(param.getPageNum(), param.getPageSize());
        QueryWrapper<GoodsValueRecords> wrapper = new QueryWrapper<>();
        if (ObjectUtil.isNotEmpty(param.getAdminName())){
            wrapper.eq("create_by",param.getAdminName());
        }
        wrapper.select("DISTINCT goods_id").orderByDesc("create_time");
        page(page,wrapper);
        IPage<ValueRecordDto> iPage = page.convert(v -> {
            ValueRecordDto dto = new ValueRecordDto();
            BeanUtil.copyProperties(v, dto);
            return dto;
        });
        List<ValueRecordDto> newList = new ArrayList<>();
        for (ValueRecordDto record : iPage.getRecords()) {
            ValueRecordDto newRecord = findNewValueByGoodsId(record.getGoodsId());
            newList.add(newRecord);
        }
        iPage.setRecords(newList);
        return iPage;
    }
}
